﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using LunchCommand.Data;
using LunchCommand.Models;
using LunchCommand.Services;
using LunchCommand.Models.Logging;
using System.Data.Entity;

namespace Tests.LunchServiceTests
{
    [TestClass]
    public abstract class BaseLunchServiceTest
    {
        protected LunchService Service { get; set; }

        protected WebConfigSettings Settings { get; set; }

        protected LunchCommandContext DatabaseContext { get; set; }

        protected User UserAlpha { get; set; }
        protected User UserBravo { get; set; }
        protected User UserCharlie { get; set; }

        protected Venue BurgerJoint { get; set; }
        protected Venue SushiBar { get; set; }
        protected Venue WaffleHouse { get; set; }
        protected Venue PizzaPlace { get; set; }
        protected Venue Tacos { get; set; }
        protected Venue SlopShop { get; set; }

        protected Genre Mexi { get; set; }
        protected Genre Sushi { get; set; }
        protected Genre American { get; set; }
        protected Genre Pizza { get; set; }

        protected IList<Lunch> Lunches { get; set; }

        [TestInitialize]
        public void Setup()
        {
            this.DatabaseContext = new LunchCommandContext();
            this.DatabaseContext.Database.BeginTransaction();

            this.UserAlpha = new User()
            {
                Name = "Alpha",
                WindowsUsername = "Alpha"
            };

            this.UserBravo = new User()
            {
                Name = "Bravo",
                WindowsUsername = "Bravo"
            };

            this.UserCharlie = new User()
            {
                Name = "Charles",
                WindowsUsername = "Chuck"
            };

            this.UserAlpha.VenueDecisions = new List<UserVenueChoice>();
            this.UserBravo.VenueDecisions = new List<UserVenueChoice>();
            this.UserCharlie.VenueDecisions = new List<UserVenueChoice>();

            this.DatabaseContext.Users.Add(this.UserAlpha);
            this.DatabaseContext.Users.Add(this.UserBravo);
            this.DatabaseContext.Users.Add(this.UserCharlie);

            this.Sushi = "Sushi";
            this.Mexi = "Mexi";
            this.American = "Tasty";
            this.Pizza = "PIZZA!";

            this.DatabaseContext.Genres.Add(this.Sushi);
            this.DatabaseContext.Genres.Add(this.Mexi);
            this.DatabaseContext.Genres.Add(this.American);
            this.DatabaseContext.Genres.Add(this.Pizza);

            this.SushiBar = new Venue()
            {
                Genre = this.Sushi,
                Name = "Sushi"
            };

            this.PizzaPlace = new Venue()
            {
                Genre = this.Pizza,
                Name = "Papa John's"
            };

            this.WaffleHouse = new Venue()
            {
                Genre = this.American,
                Name = "Waffle House"
            };

            this.SlopShop = new Venue()
            {
                Name = "Mc Donalds",
                Genre = this.American
            };

            this.Tacos = new Venue()
            {
                Name = "Paco's",
                Genre = this.Mexi
            };

            this.BurgerJoint = new Venue()
            {
                Name = "Bobby's",
                Genre = this.American
            };

            this.DatabaseContext.Venues.Add(this.BurgerJoint);
            this.DatabaseContext.Venues.Add(this.PizzaPlace);
            this.DatabaseContext.Venues.Add(this.SlopShop);
            this.DatabaseContext.Venues.Add(this.SushiBar);
            this.DatabaseContext.Venues.Add(this.WaffleHouse);
            this.DatabaseContext.Venues.Add(this.Tacos);

            this.DatabaseContext.SaveChanges();

            this.Settings = new WebConfigSettings();
            this.Settings.LunchStartTime = new TimeSpan(12, 0, 0);
            this.Settings.NumberOfDaysBeforeVenuesAreConsideredEquiallyOld = 14;

            this.Service = new LunchService(this.DatabaseContext, this.Settings, new DatabaseLogger(new LogRepository(this.DatabaseContext)));
        }

        [TestCleanup]
        public void Teardown()
        {
            this.DatabaseContext.Database.CurrentTransaction.Rollback();
            this.DatabaseContext.Dispose();
        }

        protected void LikeAllOfThem(User user)
        {
            foreach (var venue in this.DatabaseContext.Venues)
            {
                user.VenueDecisions.Add(new UserVenueChoice()
                {
                    User = user,
                    Venue = venue,
                    Degree = DegreeOfPreference.WillGo
                });
            }
        }
    }
}
